
import 'dart:convert';
import 'dart:io';

import 'package:ceramics/extensions/ab_list_extensions.dart';
import 'package:ceramics/extensions/ab_string_extensions.dart';
import 'package:ceramics/util/ab_api.dart';
import 'package:get/get.dart';
import 'package:path_provider/path_provider.dart';

class OssCaches {
  static List<OSSResponse> ossCaches = [];
  static Future<List<OSSResponse>> initLocalCaches() async {
    var docPath = await getApplicationDocumentsDirectory();
    var ossPath = '${docPath.path}/oss.json';
    var file = File(ossPath);
    if (file.existsSync()) {
      var content = await file.readAsString();
      jsonDecode(content).forEach((element) {
        var ossRes = OSSResponse.fromJson(element);
        if (!ossRes.mediaUrl.isExpired() && !ossCaches.containsWhere((element) => element.mediaPath == ossRes.mediaPath)){
          ossCaches.add(ossRes);
        }
      });
    }
    return ossCaches;
  }

  static updateToLocalCache() async {
    var docPath = await getApplicationDocumentsDirectory();
    var ossPath = '${docPath.path}/oss.json';
    var file = File(ossPath);
    var jsonList = ossCaches.map((e) => e.toJson()).toList();
    var content = jsonEncode(jsonList);
    await file.writeAsString(content);
  }
}

extension OSSReplaceMap on Map<String,dynamic> {
  /// typeDict like {'avatar':'image','video':'video'}
  List<OSSRequest> allWillConvertValueWithKeys(Map<String,String> typeDict) {
    List<OSSRequest> allRequest = [];
    for (var key in keys) {
      var value = this[key];
      if (typeDict.keys.contains(key)) {
        if (value is String) {
          allRequest.add(OSSRequest(value, typeDict[key]!));
        }
      } else if (value is List) {
        for (var dict in value) {
          allRequest.addAll(dict.allWillConvertValueWithKeys(typeDict));
        }
      }
    }
    return allRequest;
  }
}

extension OSSReplaceList on List<Map<String,dynamic>> {
  Future<List<Map<String,dynamic>>> replaceOSSURL(Map<String,String> keys) async {
    List<OSSRequest> allWillConvertRequest = [];
    List<Map<String,dynamic>> a = List.from(this);
    for (var dict in this) {
      allWillConvertRequest.addAll(dict.allWillConvertValueWithKeys(keys));
    }
    allWillConvertRequest = allWillConvertRequest.filter((element) => !OssCaches.ossCaches.containsWhere((a) => a.mediaPath == element.mediaPath));
    var result = OssCaches.ossCaches;
    if (allWillConvertRequest.isNotEmpty) {
      var r1 = await api.fetchOssURL(allWillConvertRequest);
      if (r1.isNotEmpty) {
        result.addAllIf(!OssCaches.ossCaches.containsWhere((a) => r1.containsWhere((b) => a.mediaPath ==  b.mediaPath)), r1);
        OssCaches.ossCaches = result;
        await OssCaches.updateToLocalCache();
      }
    }
    for (int i = 0; i < length; i++) {
      var value = a[i];
      for (var key in keys.keys) {
        var v1 = value[key];
        if (v1 is String) {
          for (var v2 in result) {
            if (v2.mediaPath == v1) {
              var dict = Map.from(a[i]);
              dict['${key}_oss'] = v2;
              a[i] = dict.cast();
            }
          }
        } else if (v1 is List<Map<String,dynamic>>) {
          var r = await v1.replaceOSSURL(keys);
          var dict = Map.from(a[i]);
          dict[key] = r;
          a[i] = dict.cast();
        }
      }
    }
    return a;
  }
}
